<template>
    <view
        :class="
            'l-tabs l-class-tabs l-tabs-class ' +
            ('l-placement-' + placement) +
            ' ' +
            (animated ? 'l-aminmated' : '') +
            ' ' +
            (placement === 'left' || placement === 'right' ? 'l-tabs-vertical' : 'l-tabs-horizontal') +
            ' ' +
            (scrollable ? 'l-tabs-scroll' : '')
        "
    >
        <scroll-view
            :scroll-x="placement === 'top' || (placement === 'bottom' && scrollable)"
            :scroll-y="placement === 'left' || (placement === 'right' && scrollable)"
            :scroll-top="transformY"
            :scroll-left="transformX"
            scroll-with-animation
            :class="'l-tabsscroll l-class-header l-header-class ' + (hasLine ? 'l-tabs-header-line l-class-header-line l-header-line-class' : '')"
        >
            <view class="l-tabs-header">
                <view
                    :class="
                        'l-tabs-item ' +
                        (equalWidth ? 'l-tabs-equal-width' : 'l-tabs-unequal-width') +
                        ' ' +
                        (item.key === activeKeyClone ? 'l-class-active l-active-class l-tabs-active' : 'l-class-inactive l-inactive-class l-tabs-inactive') +
                        ' ' +
                        ('l-tab-image-placement-' + item.picPlacement)
                    "
                    :style="'color:' + (item.key === activeKeyClone ? activeColor : inactiveColor)"
                    :data-key="item.key"
                    :data-index="index"
                    mut-bind:tap="handleChange"
                    v-for="(item, index) in tabList"
                    :key="index"
                >
                    <image
                        v-if="item.image.activeImage || item.image.defaultImage"
                        :src="item.key === activeKeyClone ? item.image.activeImage : item.image.defaultImage"
                        class="l-tab-image l-class-tabimage l-tabimage-class"
                    />

                    <l-icon
                        v-if="item.icon"
                        :l-class="'l-class-icon l-icon-class ' + (item.key === activeKeyClone ? 'l-icon-active' : 'l-icon-inactive')"
                        :name="item.icon"
                        :color="item.key === activeKeyClone ? activeColor : inactiveColor"
                        :size="item.iconSize"
                    />

                    {{ item.tab }}

                    <slot v-if="!item.tab" :name="item.key + '.tab'"></slot>

                    <view
                        :class="'l-tab-line ' + (item.key === activeKeyClone ? 'l-class-line l-line-class' : '') + ' ' + (animatedForLine ? 'l-line-aminmated' : '')"
                        v-if="hasLine"
                        :style="'background:' + (item.key === activeKeyClone ? activeColor : inactiveColor)"
                    ></view>
                </view>
            </view>
        </scroll-view>
        <view
            v-if="!swipeable"
            class="l-tabpanel-content l-class-content l-content-class"
            :style="
                (contentHeight ? 'height:' + contentHeight + 'rpx;' : '') +
                (placement === 'top' || placement === 'bottom'
                    ? 'margin-left:' + -100 * currentIndex + '%;'
                    : 'transform:translate(0,' + -100 * currentIndex + '%) translateZ(0px);')
            "
        >
            <view
                :class="'l-tabpanel ' + (item.key === activeKeyClone ? 'l-tabpanel-active' : 'l-tabpanel-inactive')"
                :style="
                    placement === 'left' || placement === 'right' ? 'position:absolute;width:100%;height:100%;transform:translate(0,' + 100 * index + '%) translateZ(0px);' : ''
                "
                v-for="(item, index) in tabList"
                :key="index"
            >
                <slot :name="item.key"></slot>
            </view>
        </view>
        <swiper
            v-else
            class="l-tabpanel-content l-tabpanel-swiper l-class-content l-content-class"
            @change="swiperChange"
            :style="contentHeight ? 'height:' + contentHeight + 'rpx;' : ''"
            :current="currentIndex"
            :vertical="placement === 'left' || placement === 'right'"
        >
            <swiper-item :class="'l-tabpanel ' + (item.key === activeKeyClone ? 'l-tabpanel-active' : '')" v-for="(item, index) in tabList" :key="index">
                <slot :name="item.key"></slot>
            </swiper-item>
        </swiper>
    </view>
</template>

<script>
import lIcon from '../icon/index';
import lBadge from '../badge/index';
import lTabpanel from '../tabpanel/index';
import scrollCenter from '../behaviors/scrollCenter';
export default {
    unicomGroup: ['tabpanel'],
    data() {
        return {
            tabList: [],
            currentIndex: 0,
            transformX: 0,
            transformY: 0,
            activeKeyClone: ''
        };
    },
    mixins: [scrollCenter],
    externalClasses: [
        'l-class-tabs',
        'l-class-header',
        'l-class-active',
        'l-class-content',
        'l-class-inactive',
        'l-class-line',
        'l-class-tabimage',
        'l-class-header-line',
        'l-class-icon',
        'l-tabs-class',
        'l-header-class',
        'l-active-class',
        'l-content-class',
        'l-inactive-class',
        'l-line-class',
        'l-tabimage-class',
        'l-header-line-class',
        'l-icon-class'
    ],
    relations: {
        '../tabpanel/index': {
            type: 'child',
            linked() {
                this.initTabs();
            }
        }
    },
    options: {
        multipleSlots: true
    },
    props: {
        activeKey: {
            type: String,
            default: ''
        },
        placement: {
            type: String,
            default: 'top'
        },
        animated: Boolean,
        swipeable: Boolean,
        scrollable: Boolean,
        hasLine: {
            type: Boolean,
            default: true
        },
        animatedForLine: Boolean,
        activeColor: {
            type: String,
            default: '#333333'
        },
        inactiveColor: {
            type: String,
            default: '#bbbbbb'
        },
        equalWidth: {
            type: Boolean,
            default: true
        },
        contentHeight: Number
    },
    watch: {
        activeKey: function (e) {
            if (!e) {
                return;
            }
            const t = this.tabList.findIndex((t) => t.key === e);
            this.setData(
                {
                    currentIndex: t
                },
                () => {
                    if (this.scrollable) {
                        this.queryMultipleNodes();
                    }
                }
            );
        }
    },
    mounted() {
        // 处理小程序 ready 生命周期
        this.$nextTick(() => this.ready());
    },
    methods: {
        ready() {
            this.initTabs();
        },

        initTabs(e = this.activeKeyClone) {
            let t = this.getRelationNodes('tabpanel');
            if (t.length > 0) {
                let a = e;
                let s = this.currentIndex;
                const i = t.map(
                    (t, i) => (
                        e || 0 !== i ? (a = a) : (a = t.data.key),
                        t.data.key === a ? (s = i) : (s = s),
                        {
                            tab: t.data.tab,
                            key: t.data.key,
                            icon: t.data.icon,
                            iconSize: t.data.iconSize,
                            image: t.data.image,
                            picPlacement: t.data.picPlacement
                        }
                    )
                );
                this.setData(
                    {
                        tabList: i,
                        activeKeyClone: a,
                        currentIndex: s
                    },
                    () => {
                        if (this.scrollable) {
                            this.queryMultipleNodes();
                        }
                    }
                );
            }
        },

        swiperChange(e) {
            const { source: t, current: a } = e.detail;
            if ('touch' === t) {
                const e = a;
                const t = this.tabList[a].key;
                this._setChangeData({
                    activeKey: t,
                    currentIndex: e
                });
            }
        },

        handleChange(e) {
            const t = e.currentTarget.dataset.key;
            const a = e.currentTarget.dataset.index;
            this._setChangeData({
                activeKey: t,
                currentIndex: a
            });
        },

        _setChangeData({ activeKey: e, currentIndex: t }) {
            this.setData(
                {
                    activeKeyClone: e,
                    currentIndex: t
                },
                () => {
                    if (this.scrollable) {
                        this.queryMultipleNodes();
                    }
                }
            );
            this.$emit('linchange', {
                detail: {
                    activeKey: e,
                    currentIndex: t
                }
            });
        }
    },
    created: function () {}
};
</script>
<style>
.l-tabs {
    display: flex;
    border-radius: 8rpx;
    box-sizing: border-box;
    overflow: hidden;
    flex-direction: column;
    height: 100%;
}
.l-tabs .l-tabs-header {
    display: flex;
    width: 100%;
    flex-direction: row;
    background: #fff;
    align-items: center;
}
.l-tabs .l-tabs-header .l-tabs-item {
    font-size: 28rpx;
    text-align: center;
    box-sizing: border-box;
    display: flex;
    justify-content: center;
    align-items: center;
}
.l-tabs .l-tabs-header .l-tabs-equal-width {
    flex: 1;
}
.l-tabs .l-tabs-header .l-tabs-unequal-width {
    padding: 0 20rpx;
}
.l-tabs .l-tabs-header .l-icon-active,
.l-tabs .l-tabs-header .l-tabs-active {
    color: #333;
    font-size: 28rpx;
}
.l-tabs .l-tabs-header .l-icon-inactive,
.l-tabs .l-tabs-header .l-tabs-inactive {
    font-size: 28rpx;
    color: #bbb;
}
.l-tabs .l-tabs-header .l-tabsitems-row {
    flex-direction: row;
}
.l-tabs .l-tabs-header .l-tabsitems-row .l-icon-active,
.l-tabs .l-tabs-header .l-tabsitems-row .l-icon-inactive {
    margin-right: 10rpx;
}
.l-tabs .l-tabs-header .l-tabsitems-row-reverse {
    flex-direction: row-reverse;
}
.l-tabs .l-tabs-header .l-tabsitems-row-reverse .l-icon-active,
.l-tabs .l-tabs-header .l-tabsitems-row-reverse .l-icon-inactive {
    margin-left: 10rpx;
}
.l-placement-bottom .l-tabs-header,
.l-placement-top .l-tabs-header {
    height: 80rpx;
}
.l-placement-bottom .l-tabs-header .l-tabs-item,
.l-placement-top .l-tabs-header .l-tabs-item {
    min-height: 100%;
}
.l-placement-left,
.l-placement-right {
    flex-direction: row;
}
.l-placement-left .l-tabs-header,
.l-placement-right .l-tabs-header {
    flex-direction: column;
    width: 160rpx;
}
.l-placement-left .l-tabs-header > .l-tabs-item,
.l-placement-right .l-tabs-header > .l-tabs-item {
    width: 100%;
    height: 80rpx;
    background: #f6f8fa;
}
.l-placement-left .l-tabs-header > .l-tabs-active,
.l-placement-right .l-tabs-header > .l-tabs-active {
    background: #fff;
}
.l-placement-right {
    flex-direction: row-reverse;
}
.l-placement-bottom {
    flex-direction: column-reverse;
}
.l-tabpanel-content {
    display: flex;
}
.l-placement-left .l-tabpanel-content,
.l-placement-right .l-tabpanel-content {
    width: 100%;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    flex-direction: column;
    position: relative;
    will-change: transform;
    transition: transform 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}
.l-tabs-vertical .l-tabpanel-swiper {
    height: initial;
}
.l-placement-bottom .l-tabpanel-content,
.l-placement-top .l-tabpanel-content {
    width: 100%;
    min-height: 100%;
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-orient: horizontal;
    -webkit-box-direction: normal;
    -webkit-flex-direction: row;
    -ms-flex-direction: row;
    flex-direction: row;
}
.l-aminmated.l-placement-bottom .l-tabpanel-content,
.l-aminmated.l-placement-top .l-tabpanel-content {
    will-change: margin-left;
    -webkit-transition: margin-left 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
    transition: margin-left 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}
.l-tabpanel {
    width: 100%;
    height: 100%;
    -webkit-flex-shrink: 0;
    -ms-flex-negative: 0;
    flex-shrink: 0;
    opacity: 1;
    text-overflow: ellipsis;
}
.l-tabpanel-inactive {
    opacity: 0;
    height: 0;
    padding: 0 !important;
    pointer-events: none;
}
.l-tabs-scroll.l-tabs-horizontal .l-tabs-header {
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
}
.l-tabs-scroll.l-tabs-horizontal .l-tabs-header .l-tabs-item {
    overflow: visible;
}
.l-tabs-vertical .l-tabsscroll {
    width: 160rpx;
}
.l-tabs-vertical .l-tabs-header {
    height: 100%;
    min-height: 80rpx;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
}
.l-tabs-vertical .l-tabs-header .l-tabs-item {
    overflow: visible;
    min-height: 80rpx;
}
.l-tabs-item {
    position: relative;
}
.l-tab-line {
    position: absolute;
    bottom: 0;
    left: 0;
    background: #000;
}
.l-tabs-horizontal .l-tab-line {
    height: 4rpx;
    width: 0;
    left: 100%;
    right: 0;
    margin: 0 auto;
}
.l-tabs-horizontal .l-line-aminmated {
    transition: 0.2s all linear;
}
.l-tabs-horizontal .l-tabs-active.l-tabs-item ~ .l-tabs-item .l-tab-line {
    left: 0;
}
.l-tabs-horizontal .l-tabs-active .l-tab-line {
    width: 100%;
    left: 0;
}
.l-tabs-horizontal .l-tabs-active .l-line-aminmated {
    transition-delay: 0.1s;
}
.l-placement-top .l-tab-line {
    bottom: 0;
}
.l-placement-top .l-tabs-header-line {
    border-bottom: 1px solid #f3f3f3;
}
.l-placement-bottom .l-tab-line {
    top: 0;
}
.l-placement-bottom .l-tabs-header-line {
    border-top: 1px solid #f3f3f3;
}
.l-tabs-vertical .l-tab-line {
    width: 6rpx;
    height: 0;
    border-radius: 0 6rpx 6rpx 0;
    top: 0;
    margin: auto 0;
}
.l-tabs-vertical .l-line-aminmated {
    transition: 0.2s all linear;
}
.l-tabs-vertical .l-tabs-active .l-tab-line {
    height: 40rpx;
}
.l-tabs-vertical .l-tabs-active .l-line-aminmated {
    transition-delay: 0.1s;
}
.l-tabs-vertical .l-tabs-active.l-tabs-item ~ .l-tabs-item .l-tab-line {
    height: 0;
    top: 0;
}
.l-placement-left .l-tab-line {
    right: auto;
}
.l-placement-left .l-tabs-header-line {
    border-left: 1px solid #f3f3f3;
}
.l-placement-right .l-tab-line {
    right: 0;
    left: auto;
}
.l-placement-right .l-tabs-header-line {
    border-right: 1px solid #f3f3f3;
}
.l-tab-image {
    width: 100rpx;
    height: 100rpx;
}
.l-tab-image-placement-top {
    flex-direction: column;
}
.l-tab-image-placement-bottom {
    flex-direction: column-reverse;
}
.l-tab-image-placement-left {
    flex-direction: row;
}
.l-tab-image-placement-right {
    flex-direction: row-reverse;
}
</style>
